#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include "libconfig.h"
#include "InComStringHandling.h"
#include "InSdkDevInfo.h"

#define DEF_TAG             "GetDevInfo"

Com_s32 Ext_InSdkGetInfo_export(Com_ps8 param,Com_ps8 contest)
{
    Com_s32 len;
    Com_s8 str[128];
    Com_s8 src[DEF_COM_EXPORT_LEN];
    FILE *fp;

    memset(str,0,sizeof(str));
    memset(src,0,sizeof(src));

    sprintf(str,"export | grep %s | awk -F \"'\" '{print $2}'",param);
    fp = popen(str,"r");
    if(!fp)
    {
        perror("popen export fp");
        return -1;
    }

    fgets(src,sizeof(src),fp);
    len = strlen(src);
    src[len - 1] = '\0';
    strcpy(contest,src);
    PRT_DBG(DEF_TAG,"export src = %s\n",src);
    pclose(fp);

    return 0;
}

Com_s32 Ext_InSdkGetInfo_UUID(char *uuid)
{
    ComNullRetInt(uuid);

    if(Ext_InComFile_Access(DEF_INI_IOT_CONFIG) == DEF_COM_FILE_NOT_EXIST)
    {
        return -1;
    }

    struct config *conf = conf_load(DEF_INI_IOT_CONFIG);
    strcpy(uuid,conf_get_string(conf, "cfg:uuid"));
    conf_unload(conf);
    PRT_DBG(DEF_TAG,"uuid: %s\n",uuid);
    return 0;
}

Com_s32 Ext_InSdkGetInfo_Authkey(char *key)
{
    ComNullRetInt(key);

    if(Ext_InComFile_Access(DEF_INI_IOT_CONFIG) == DEF_COM_FILE_NOT_EXIST)
    {
        return -1;
    }

    struct config *conf = conf_load(DEF_INI_IOT_CONFIG);
    strcpy(key,conf_get_string(conf, "cfg:authkey"));
    conf_unload(conf);
    PRT_DBG(DEF_TAG,"authkey: %s\n",key);
    return 0;
}

Com_s32 Ext_InSdkGetInfo_Pid(char *pid)
{
    ComNullRetInt(pid);

    if(Ext_InComFile_Access(DEF_INI_IOT_CONFIG) == DEF_COM_FILE_NOT_EXIST)
    {
        return -1;
    }

    struct config *conf = conf_load(DEF_INI_IOT_CONFIG);
    strcpy(pid,conf_get_string(conf, "cfg:pid"));
    conf_unload(conf);
    PRT_DBG(DEF_TAG,"pid: %s\n",pid);
    return 0;
}

Com_s32 Ext_InSdkGetInfo_SocVer(char *ver)
{
    ComNullRetInt(ver);

    if(Ext_InComFile_Access(DEF_TXT_SOC_VERSION) == DEF_COM_FILE_NOT_EXIST)
    {
        return -1;
    }

    int len;
    len = Ext_InComFile_ReadStr(DEF_TXT_SOC_VERSION, ver, DEF_COM_VERSION_LEN);
    if (len <= 0)
    {
        strcpy(ver, DEF_DEFAULT_VERSION);
    }
    Ext_InComStrHandle_RemoveLastLines(ver);
    PRT_DBG(DEF_TAG, "soc ver: %s\n", ver);

    return 0;
}

Com_s32 Ext_InSdkGetInfo_AllVer(char *ver)
{
    ComNullRetInt(ver);

    if(Ext_InComFile_Access(DEF_TXT_SOC_VERSION) == DEF_COM_FILE_NOT_EXIST)
    {
        return -1;
    }

    int len;
    len = Ext_InComFile_ReadStr(DEF_TXT_SOC_VERSION,ver,DEF_COM_VERSION_LEN);
    if (len <= 0)
    {
        strcpy(ver, DEF_DEFAULT_VERSION);
    }

    /* get mcu version */
    if (Ext_InComFile_Access(DEF_TXT_MCU_VERSION) == DEF_COM_FILE_EXIST)
    {
        Com_u32 ver1 = 0, ver2 = 0, ver3 = 0;
        Com_u32 ver_num = 0;
        Com_s8 mcu_ver[4] = {0};
        Ext_InComFile_ReadStr(DEF_TXT_MCU_VERSION, mcu_ver, sizeof(mcu_ver));
        ver_num = atoi(mcu_ver);

        sscanf(ver, "%d.%d.%d", &ver1, &ver2, &ver3);
        memset(ver, 0, DEF_COM_VERSION_LEN);
        sprintf(ver, "%d.%02d.%02d", ver1, ver_num, ver3);
    }
    Ext_InComStrHandle_RemoveLastLines(ver);
    PRT_DBG(DEF_TAG,"version: %s\n",ver);

    return 0;
}

Com_s32 Ext_InSdkGetInfo_HardwareMac(Com_ps8 mac, EComHardwareMacType type)
{
    struct ifreq ifreq;
    int sock;

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("socket");
        return -2;
    }

    strcpy(ifreq.ifr_name, "wlan0");
    if (ioctl(sock, SIOCGIFHWADDR, &ifreq) < 0)
    {
        perror("ioctl");
        return -3;
    }

    switch (type)
    {
    case MAC_SRC:
    {
        sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
                (unsigned char)ifreq.ifr_hwaddr.sa_data[0],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[1],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[2],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[3],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[4],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[5]);
    }
    break;

    case MAC_STR:
    {
        sprintf(mac, "%02x%02x%02x%02x%02x%02x",
                (unsigned char)ifreq.ifr_hwaddr.sa_data[0],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[1],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[2],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[3],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[4],
                (unsigned char)ifreq.ifr_hwaddr.sa_data[5]);
    }
    break;

    case MAC_HEX:
    {
        int i;

        for (i = 0; i < 6; i++)
        {
            mac[i] = (unsigned char)ifreq.ifr_hwaddr.sa_data[i];
        }
    }
    break;

    default:
        break;
    }

    return 0;
}

Com_void Ext_InSdkGetInfo_WiFiRssi(_OUT Com_ps8 rssi)
{
    FILE *wifi_fp;
    int wifi_len;

    wifi_fp = popen("iwconfig wlan0|grep \"level=\"|awk -F \"level=\" '{print $2}'|awk -F ' ' '{print $1}'", "r");
    if (!wifi_fp)
    {
        perror("popen wifi_fp");
        return;
    }
    fgets(rssi, DEF_COM_WIFI_RSSI_LEN, wifi_fp);
    wifi_len = strlen(rssi);

    if (strstr(rssi, "/") != NULL)
    {
        rssi[wifi_len] = '\0';
        int rssi_val = 0;
        int level_a = 0, level_b = 0;
        sscanf(rssi, "%d/%d", &level_a, &level_b);
        rssi_val = (level_a - 1) * 100 / level_b;
        rssi_val = 100 - rssi_val;
        memset(rssi, 0, wifi_len);
        PRT_INFO(DEF_TAG, "new modle\n");
        sprintf(rssi, "-%d", rssi_val);
    }
    else
    {
        rssi[wifi_len - 1] = '\0';
    }

    if (wifi_len <= 1)
    {
        strcpy(rssi, "-1");
    }

    PRT_INFO(DEF_TAG, "rssi: %s\n", rssi);
    pclose(wifi_fp);
}

Com_void Ext_InSdkGetInfo_WiFiQuality(_OUT Com_ps32 rssi)
{
    if(NULL == rssi)
    {
        return;
    }
    *rssi = 0;

    FILE *pp = popen("iwconfig "DEF_COM_WLAN_DEV, "r");
    if(pp == NULL)
    {
        return;
    }

    char tmp[128] = {0};
    while (fgets(tmp, sizeof(tmp), pp) != NULL)
    {
        /* find signal  */
        char *pSIGNALStart = strstr(tmp, "Quality=");
        if(pSIGNALStart != NULL)
        {
            int x = 0;
            int y = 0;
            sscanf(pSIGNALStart + strlen("Quality="), "%d/%d",&x,&y);
            *rssi = x * 100/ (y+1);
            break;
        }
    }
    pclose(pp);
}

Com_void Ext_InSdkGetInfo_WiFiEssid(_OUT Com_ps8 ssid)
{
    if(NULL == ssid)
    {
        PRT_INFO(DEF_TAG,"essid buf is NULL\n");
        return;
    }

    FILE *pp = popen("iwconfig "DEF_COM_WLAN_DEV, "r");
    if(pp == NULL)
    {
        return;
    }

    int len = 0;
    char tmp[128] = {0};
    while (fgets(tmp, sizeof(tmp), pp) != NULL)
    {
        /* find signal  */
        char *pSSIDStart = strstr(tmp, "ESSID:\"");
        if(pSSIDStart != NULL)
        {
            sscanf(pSSIDStart + strlen("ESSID:\""), "%s", ssid);
            len = strlen((char *)ssid);
            if(len != 0)
            {
                ssid[len - 1] = 0;
            }
            PRT_INFO(DEF_TAG,"essid: %s\n",ssid);
            break;
        }
    }
    pclose(pp);
}

Com_s32 Ext_InSdkGetInfo_WiFiFrequency(Com_void)
{
    FILE *pp = popen("iwconfig "DEF_COM_WLAN_DEV, "r");
    if(pp == NULL)
    {
        return E_WIFI_FREQUENCY_2_4_G;
    }

    int len = 0;
    char tmp[128] = {0};
    char wifi_freq[32] = {0};

    while (fgets(tmp, sizeof(tmp), pp) != NULL)
    {
        /* find signal  */
        char *pSSIDStart = strstr(tmp, "Frequency:");
        if(pSSIDStart != NULL)
        {
            sscanf(pSSIDStart + strlen("Frequency:"), "%s", wifi_freq);
            len = strlen((char *)wifi_freq);
            if(len != 0)
            {
                wifi_freq[len - 1] = 0;
            }
            //PRT_INFO(DEF_TAG,"wifi_freq: %s\n",wifi_freq);
            break;
        }
    }
    pclose(pp);

    if(strstr(wifi_freq,"2.") != NULL)
    {
        //PRT_NORMAL("2.4G wifi\n");
        return E_WIFI_FREQUENCY_2_4_G;
    }
    else if(strstr(wifi_freq,"5.") != NULL)
    {
        //PRT_NORMAL("5G wifi\n");
        return E_WIFI_FREQUENCY_5_G;
    }

    return E_WIFI_FREQUENCY_2_4_G;
}

Com_s32 Ext_InSdkGetInfo_WiFi_IP(_OUT Com_ps8 ip)
{
    int sock;

    struct sockaddr_in *sin;
    struct ifreq ifr;

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        PRT_ERR(DEF_TAG, "socket create failse...GetLocalIp!\n");
        return -1;
    }

    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, DEF_COM_WLAN_DEV, sizeof(ifr.ifr_name) - 1);

    if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
    {
        PRT_ERR(DEF_TAG, "ioctl error\n");
        close(sock);
        return -1;
    }

    sin = (struct sockaddr_in *)&ifr.ifr_addr;
    strcpy(ip, inet_ntoa(sin->sin_addr));
    close(sock);

    // printf("WIFI[%d] Get IP:%s\r\n", wf, ip->ip);
    return 0;
}
